1. Field of the Invention
This invention relates in general to the field of microelectronics, and more particularly to a technique applied in a pipeline microprocessor to ensure the coherency of instructions in its pipeline stages.
2. Description of the Related Art
Early microprocessors were designed to execute only one program instruction at a time. Accordingly, an early microprocessor would fetch a first program instruction from program memory and the execute it. Following execution of the first instruction, the early microprocessor would fetch a second program instruction from memory and execute it. Then, a third program instruction would be fetched and executed. And so on. Because only one instruction was being executed at a particular point in time, there was no reasonable basis for prohibiting application programmers from designing programs that contained self-modifying code sections.
In its simplest form, self-modifying code is code that modifies itself. In the example above, self-modifying code would exist if, say, the result of the first program instruction were stored by the early microprocessor to the location in memory from which the third program instruction was to be fetched. Self-modifying code was employed during the days of early microprocessors for several reasons: to save memory space, to implement subroutine calls and returns, to hide instructions running in an application in order to preclude piracy (or to surreptitiously invoke a virus), to interface to particular hardware devices, or to improve overall performance. Self-modifying code techniques were not recommended for use then, nor are they recommended now because code of this sort is often times difficult to understand and maintain.
The disadvantages notwithstanding, self-modifying code it still employed today for many of the reasons stated above. But whereas early microprocessors were not adversely impacted by a requirement to support the execution of self-modifying code, today's microprocessors suffer tremendous impact in terms of the extra logic that must be provided in order to ensure the proper execution of program instructions in the presence of self-modifying code sections. This is because today's microprocessors no longer execute program instructions one-at-a-time; they operate on several instructions at the same time. Multiple instructions are simultaneously being operated upon within successive segments (i.e., “pipeline stages”) of a present day microprocessor. Hennessy and Patterson define pipelining as, “an implementation technique whereby multiple instructions are overlapped in execution.” Computer Architecture: A Quantitative Approach, second edition, by John L. Hennessy and David A. Patterson, Morgan Kaufmann Publishers, San Francisco, Calif., 1996. The authors go on to provide the following excellent illustration of pipelining: “A pipeline is like an assembly line. In an automobile assembly line, there are many steps, each contributing something to the construction of the car. Each step operates in parallel with the other steps, though on a different car. In a computer pipeline, each step in the pipeline completes a part of an instruction. Like the assembly line, different steps are completing different parts of the different instructions in parallel. Each of these steps is called a pipe stage or a pipe segment. The stages are connected one to the next to form a pipe. Instructions enter at one end, progress through the stages, and exit at the other end, just as cars would in an assembly line.”
Thus, in a present day microprocessor, instructions are fetched into one end of the pipeline, and they proceed through successive pipeline stages until they complete execution. And very much like an assembly line, a present day pipeline microprocessor is running at peak efficiency when every one of its pipeline stages is operating on a different program instruction. To stall fetching of instructions or execution of instructions while waiting for some pipeline stage to complete an operation decreases the efficiency (i.e., the throughput) of the pipeline. Yet, stalling the pipeline is often required to support many different types of operations in a present day microprocessor. For example, read and write operations to memory are notoriously slow operations that frequently require stalling the pipeline. Conditional changes in program flow (i.e., conditional branch operations) commonly result in pipeline stalls. And the presence of self-modifying code within a pipeline is yet another instance that requires the flow of instructions within a present day microprocessor pipeline to be interrupted.
Consider the example above where the result of the first program instruction is stored to the memory location corresponding to the third program instruction. If the third program instruction has already been fetched from memory and is being operated upon in an upper pipeline stage at the time when the store operation directed by the first program instruction occurs, then it follows that the third program instruction that is currently being operated upon in the upper pipeline stage is not what was intended by the application programmer. This is because the instruction intended for execution by the application programmer had not yet been stored to memory at the time when the third program instruction's memory location was accessed to fetch the third program instruction. This example illustrates a case of instruction incoherency in a pipeline due to the presence of self-modifying code, which all present day microprocessors must address. Yet, a present day microprocessor has no indication of whether it is executing self-modifying code or not. Thus, extensive logic must be provided to check the coherency of every instruction in the pipeline against every store operation that is pending or that is performed while those instructions are present in the pipeline.
Therefore, what is needed is an apparatus in a pipeline microprocessor for checking the coherency of instructions within its pipeline that is simpler and that requires less logic to implement that which has heretofore been provided.